package com.contextroot.watercooler.client;

import java.util.List;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwt.event.dom.client.KeyPressHandler;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;

/**
 * Entry point classes define <code>onModuleLoad()</code>.
 */
public class WaterCooler implements EntryPoint {

	private static final int REFRESH_INTERVAL = 5000; // ms
	private VerticalPanel mainPanel = new VerticalPanel();
	private FlexTable msgFlexTable = new FlexTable();
	private HorizontalPanel addMessagePanel = new HorizontalPanel();
	private TextBox newMsgTextBox = new TextBox();
	private Button postMsgButton = new Button("Post");
	private static final DateTimeFormat dateFormat = DateTimeFormat.getFormat("yyyy-MM-dd HH:mm:ss");
	private ChatServiceAsync chatService = GWT.create(ChatService.class);

	/**
	 * Entry point method.
	 */
	public void onModuleLoad() {
		initComponent();

		refreshMessage();

		// Setup timer to refresh list automatically.
		Timer refreshTimer = new Timer() {
			@Override
			public void run() {
				refreshMessage();
			}
		};
		refreshTimer.scheduleRepeating(REFRESH_INTERVAL);
	}

	private void initComponent() {
		// Create table for message board
		msgFlexTable.setText(0, 0, "Datetime");
		msgFlexTable.setText(0, 1, "Username");
		msgFlexTable.setText(0, 2, "Message");

		// Assemble Add Message panel.
		addMessagePanel.add(newMsgTextBox);
		addMessagePanel.add(postMsgButton);
		
		// Listen for mouse events on the Add button.
		postMsgButton.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				postMessage();
			}
		});
		
		// Listen for keyboard events in the input box.
		newMsgTextBox.addKeyPressHandler(new KeyPressHandler() {
			public void onKeyPress(KeyPressEvent event) {
				if (event.getCharCode() == KeyCodes.KEY_ENTER) {
					postMessage();
				}
			}
		});
		
		// Assemble Main panel.
		mainPanel.add(msgFlexTable);
		mainPanel.add(addMessagePanel);

		// Associate the Main panel with the HTML host page.
		RootPanel.get("waterCooler").add(mainPanel);
		
		newMsgTextBox.setFocus(true);
	}

	private void refreshMessage() {

		// Set up the callback object.
		final AsyncCallback<List<Message>> callback = new AsyncCallback<List<Message>>() {
			public void onFailure(Throwable caught) {
				// TODO: Do something with errors.
			}

			public void onSuccess(List<Message> messages) {
				// TODO Enhance logic to display delta msg instead of reload all
				// Clear previous rows
				for (int i = 1; i < msgFlexTable.getRowCount(); i++) {
					msgFlexTable.removeRow(i);
				}
				
				if (messages != null && !messages.isEmpty()) {
					// Rebuild message row
					int currentRow = 1;
					for(Message message : messages) {
						msgFlexTable.setText(currentRow, 0, dateFormat.format(message.getDatetime()));
						msgFlexTable.setText(currentRow, 1, message.getUsername());
						msgFlexTable.setText(currentRow, 2, message.getMessage());
						
						currentRow++;
					}
				}
			}
		};

		// Make the call to the stock price service.
		chatService.findAll(callback);
	}

	private void postMessage() {
		final String newMsgText = newMsgTextBox.getText();
		
		if(newMsgText != null && !"".equals(newMsgText.trim())) {
			final Message message = new Message();
			
			// TODO Add google login
			message.setMessage(newMsgText.trim());
			
			final AsyncCallback<Void> callback = new AsyncCallback<Void>() {
				public void onFailure(Throwable caught) {
					// TODO: Do something with errors.
				}

				public void onSuccess(Void result) {
					// TODO Auto-generated method stub
					
				}
			};
			
			chatService.postMessage(message, callback);
			newMsgTextBox.setText("");
			newMsgTextBox.setFocus(true);
			
			refreshMessage();
		}
	}
}
